var dyCache = {
  sendedIndex: []
}
var dyTimers = {
  hb: null,
  checkLogin: null,
  send: null
}

// MARK: 等待元素出现
async function waitSelectorUntil(selector, timeout = 5e3, doc = document) {
  return new Promise((resolve, reject) => {
    const start = Date.now()
    const timer = setInterval(() => {
      const el = doc.querySelector(selector)
      if (el) {
        clearInterval(timer)
        resolve(el)
      } else if (Date.now() - start > timeout) {
        clearInterval(timer)
        reject(new Error(`find dom [${selector}] timeout: ${timeout}ms`))
      }
    }, 100)
  })
}

async function wait(ms = 1e3) {
  return new Promise((resolve) => {
    setTimeout(resolve, ms)
  })
}

/**
 *
 * @param {string} selector
 * @returns {HTMLElement}
 */
function $(selector) {
  return document.querySelector(selector)
}
// MARK: 随机选一个
function randomOne(arr, sendedIndex) {
  if (arr.length === sendedIndex.length) {
    return null
  }

  const index = Math.floor(Math.random() * arr.length)

  if (sendedIndex.includes(index)) {
    return randomOne(arr, sendedIndex)
  }
  return {
    index,
    value: arr[index]
  }
}

function getDyConfig() {
  const config = window.DYCONFIG || {}
  const { sendInterval = 20, allCoolDown = 5 } = config
  return {
    ...config,
    sendInterval,
    allCoolDown
  }
}

function getComments() {
  const config = getDyConfig()
  const str = config.comments || ''
  return str.split('\n').filter((e) => !!e)
}

function chooseSend() {
  const config = getDyConfig()
  const comments = getComments()
  // console.log(comments)
  const { sendInterval, allCoolDown } = config
  const sendedIndex = dyCache.sendedIndex
  const comment = randomOne(comments, sendedIndex)
  if (!comment) {
    // 所有话术发送完
    if (config.sendBehavior === 1) {
      // 不再发送
      dyTimers.send && clearInterval(dyTimers.send)
      return
    }
    dyCache.sendedIndex = []
    dyTimers.send && clearInterval(dyTimers.send)
    setTimeout(() => {
      chooseSend()
      dyTimers.send = setInterval(() => {
        chooseSend()
      }, sendInterval * 1e3)
    }, allCoolDown * 6e4)
  } else {
    const { value, index } = comment
    doSendComment(value)
    dyCache.sendedIndex.push(index)
  }
}

async function doSendComment(comment) {
  const input = $('#chat-textarea')
  if (!input) {
    return
  }
  input.value = comment
  for (var key in input) {
    if (key.startsWith('__reactProps$')) {
      input[key].onChange({ target: { value: comment } })
    }
  }

  await new Promise((resolve) => {
    setTimeout(resolve, 1000)
  })
  const sendBtn = $('.webcast-chatroom___send-btn.btn-icon')
  if (sendBtn) {
    for (var key in sendBtn) {
      if (key.startsWith('__reactProps$')) {
        sendBtn[key].onClick({ stopPropagation: () => {} })
      }
    }
  }
}

function checkLogin() {
  const avatar = $('div[id^=douyin-header] .semi-avatar')
  if (avatar) {
    return true
  }
}

function emitReactDom(dom, ev) {
  ev = ev.charAt(0).toUpperCase() + ev.slice(1)
  for (var key in dom) {
    if (key.startsWith('__reactProps$')) {
      try {
        dom[key][`on${ev}`]({ stopPropagation: () => {} })
      } catch (error) {
        console.log(error)
      }
    }
  }
}

// MARK: 模拟活跃
async function mockActive() {
  const gift = $('div[data-e2e=gifts-container]>div.gift_item_gift_bar:nth-child(6)')
  if (gift) {
    emitReactDom(gift, 'mouseEnter')
    const sendDom = await waitSelectorUntil(
      'div[data-e2e=gifts-container]>div.gift_item_gift_bar:nth-child(6) div[data-e2e=gift-btn]'
    )
    if (sendDom) {
      emitReactDom(sendDom, 'click')
      const iframe = await waitSelectorUntil(
        '.webcast_recharge_iframe.webcast_recharge_iframe_loaded'
      )
      if (iframe) {
        const doc = iframe.contentDocument
        const closeBtn = await waitSelectorUntil(
          '.recharge-dialog button.rc-dialog-close',
          5e3,
          doc
        )
        if (closeBtn) {
          emitReactDom(closeBtn, 'click')
        }
      }
    }
    // 关闭充值弹窗
  }
}

async function run() {
  const config = getDyConfig()

  const { sendInterval } = config

  dyTimers.hb && clearInterval(dyTimers.hb)
  // mockActive()

  dyTimers.hb = setInterval(async () => {
    // 心跳
    mockActive()
  }, 3e4)

  dyTimers.send && clearInterval(dyTimers.send)
  dyTimers.send = setInterval(() => {
    chooseSend()
  }, sendInterval * 1e3)
}

async function main() {
  dyTimers.checkLogin && clearInterval(dyTimers.checkLogin)
  dyTimers.checkLogin = setInterval(() => {
    const isLogin = checkLogin()
    console.log('isLogin', isLogin)
    if (!isLogin) {
      return
    }
    clearInterval(dyTimers.checkLogin)
    run()
  }, 1e3)
}
main()
